import React from 'react'
import { View, ScrollView, Text, StyleSheet, NativeScrollEvent, NativeSyntheticEvent, TouchableOpacity, Alert } from 'react-native'
import { PickerViewProps, PickerData, PickerViewState } from './PropTypes'

const scrollViewRef: ScrollView[] | null[] = []

export default class PickerView extends React.Component<PickerViewProps, PickerViewState> {
  public static defaultProps = {
    list: [
      // [
      //   { label: '南京', value: '南京' },
      //   { label: '南京1', value: '南京1' },
      //   { label: '南京2', value: '南京2' },
      //   { label: '南京3', value: '南京3' },
      //   { label: '南京4', value: '南京4' }
      // ]
      // [
      //   { label: '选项2-0', value: '选项2-0' },
      //   { label: '选项2-1', value: '选项2-1' },
      //   { label: '选项2-2', value: '选项2-2' },
      //   { label: '选项2-3', value: '选项2-3' },
      //   { label: '选项2-4', value: '选项2-4' }
      // ],
      // [
      //   { label: '选项2-0', value: '选项2-0' },
      //   { label: '选项2-1', value: '选项2-1' },
      //   { label: '选项2-2', value: '选项2-2' },
      //   { label: '选项2-3', value: '选项2-3' },
      //   { label: '选项2-4', value: '选项2-4' }
      // ]
    ],
    cascade: false
  }

  public state: PickerViewState = {
    value: []
  }

  public constructor (props: PickerViewProps) {
    super(props)
    let dataList = props.list
    if (dataList && dataList.length && !(dataList[0] instanceof Array)) {
      dataList = [dataList] as PickerData[][]
    }
    let value: string[] = (dataList as PickerData[][]).map((list): string => list[0].label)
    if ('defaultValue' in props && props.defaultValue !== undefined) {
      value = props.defaultValue
    }
    if ('value' in props && props.value !== undefined) {
      value = [...props.value] // 深拷贝
    }
    this.state = {
      value
    }
  }

  public static getDerivedStateFromProps (props: PickerViewProps, state: PickerViewState): null | {value?: string[]} {
    let newValue = state.value
    if ('value' in props && props.value) {
      newValue = [...props.value]
    }
    return {
      value: newValue
    }
  }

  // public componentWillReceiveProps (nextProps: PickerViewProps): void {
  //   if ('value' in nextProps && nextProps.value) {
  //     this.setState({
  //       value: nextProps.value
  //     })
  //   }
  // }

  public componentDidUpdate (preProps: PickerViewProps, preState: PickerViewState): void {
    // this.animateScroll()
    // if (preProps.list !== this.props.list) {
    // }
    if (this.state.value.toString() !== preState.value.toString()) {
      this.animateScroll()
    }
  }

  public componentDidMount (): void {
    setTimeout((): void => {
      this.animateScroll()
    }, 150)
  }

  // 根据value滚动scrollView
  public animateScroll (value = this.state.value): void {
    let list = this.getList()
    value.map((item: string, index: number): void => {
      let top = 0
      if (!this.props.cascade) {
        top = list[index].map(item2 => item2.value).indexOf(item) * 50
      } else {
        // Alert.alert(JSON.stringify(list[index]))
        top = list[index].map(item2 => item2.value).indexOf(item) * 50
        const selectItem = list[index].find(item2 => item2.value === item)
        list = []
        list[index + 1] = (selectItem && selectItem.children) || []
      }
      setTimeout((): void => {
        if (scrollViewRef[index]) {
          (scrollViewRef[index] as ScrollView).scrollTo({ x: 0, y: top > 0 ? top : 0, animated: true })
        }
      })
    })
  }

  // 级联加载选项
  public cascadeLoadOption2 (): PickerData[][] {
    function listDeep (data: {}[], level: number = 1): number {
      const children = data.reduce((pre: {}[], next: {children?: []}): {}[] => {
        return [...pre, ...(next.children || [])]
      }, [])
      if (children.length) {
        level = listDeep(children, level + 1)
      }
      return level
    }
    const list = this.getList()
    const length = listDeep(list[0] as PickerData[])
    const value = [...(this.state.value || [])]
    while (list.length < length) {
      list.push([])
    }
    (list as PickerData[][]).map((list, index: number, array): void => {
      let selectedItem = list.find((item): boolean => item.value === value[index])
      if (!selectedItem) {
        selectedItem = list[0]
        value[index] = selectedItem.value
      }
      const nextList = selectedItem.children
      // 没有children，但是datelist的下一个层级有数据则直接清空后续的数据
      if (!('children' in selectedItem)) {
        array.splice(index + 1)
        value.splice(index + 1)
      }
      if (nextList && nextList.length) {
        array[index + 1] = nextList
        if (!nextList.some((item): boolean => item.value === value[index + 1])) {
          value[index + 1] = nextList[0].value
        }
      }
    })
    while (list.length < length) {
      list.push([])
    }
    return list
  }

  private getList (): PickerData[][] {
    let dataList = JSON.parse(JSON.stringify(this.props.list))
    if (dataList && dataList.length && !(dataList[0] instanceof Array)) {
      dataList = [dataList] as PickerData[][]
    }
    return dataList
  }

  public onMoveEnd (e: NativeSyntheticEvent<NativeScrollEvent>, viewIndex: number): void {
    const offsetY = e.nativeEvent.contentOffset.y
    const num = Math.floor(offsetY / 50)
    const index = offsetY % 50 >= 25 ? num + 1 : num
    const { value } = this.state
    const list = this.getList()
    scrollViewRef[viewIndex] && (scrollViewRef[viewIndex] as ScrollView).scrollTo({ x: 0, y: index * 50, animated: true })
    if (this.props.cascade) {
      let data = list[0]
      let i = 0
      for (i = 0; data && data.length > 0; i++) {
        if (i === viewIndex) {
          value[i] = data[index].value
          data = data[index].children || []
        } else if (i > viewIndex) {
          value[i] = data[0].value
          data = data[0].children || []
        } else {
          const preItem = data.find((item): boolean => item.value === value[i]) || data[0]
          value[i] = preItem.value
          data = (preItem && preItem.children) || []
        }
      }
      value.splice(i)
    } else {
      value[viewIndex] = list[viewIndex][index].value
    }
    this.setState({
      value
    }, () => {
      this.animateScroll(value)
    })
    this.props.onChange && this.props.onChange(value)
  }

  public renderItem (item: PickerData, index: number, parentIndex: number): JSX.Element {
    return (
      <TouchableOpacity key={index} style={[styles.picker_item]}>
        <Text style={[styles.picker_item_text, this.state.value[parentIndex] === item.value && { fontWeight: 'bold', opacity: 1, color: '#000' }]}>
          {item.label}
        </Text>
      </TouchableOpacity>
    )
  }

  public render (): JSX.Element {
    const listView = this.cascadeLoadOption2().map((list: PickerData[], index1: number): JSX.Element | JSX.Element[] => {
      return (
        <ScrollView
          key={index1}
          style={{ height: 150, flex: 1, position: 'relative', borderBottomWidth: 1, borderBottomColor: '#333' }}
          showsVerticalScrollIndicator={false} ref={(scrollView): void => { scrollViewRef[index1] = scrollView }}
          onMomentumScrollEnd={(e: NativeSyntheticEvent<NativeScrollEvent>): void => { this.onMoveEnd(e, index1) }}
        >
          <View style={[styles.picker_item]} />
          {list.map((item, index): JSX.Element => {
            return this.renderItem(item, index, index1)
          })}
          <View style={[styles.picker_item]} />
        </ScrollView>
      )
    })
    return (
      <View style={{ flexDirection: 'row' }}>
        <View style={styles.picker_selected_view} />
        {listView}
      </View>
    )
  }
}

const styles = StyleSheet.create({
  picker_item: {
    height: 50,
    justifyContent: 'center'
  },
  picker_item_text: {
    textAlign: 'center',
    textAlignVertical: 'center',
    opacity: 0.6,
    fontSize: 16
  },
  picker_selected_view: {
    position: 'absolute',
    height: 50,
    backgroundColor: '#00000008',
    width: '100%',
    top: '50%',
    marginTop: -25
  }
})
